{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Reddit Preprocessing in Stages\n",
    "\n",
    "This notebook is essentially the `reddit_preprocessor.py` file in the data package, but split into disjoint steps. This is useful for both development and visualization, e.g. you can save the data at each stage of the processing pipeline and resume later, rather than requiring a restart from beginning."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "sys.path.append('..')\n",
    "from imp import reload\n",
    "\n",
    "from data import reddit_preprocessor, DataHelper\n",
    "from data.reddit_preprocessor import *\n",
    "\n",
    "import json\n",
    "import pandas as pd\n",
    "from pprint import pprint"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using logfile: /tmp/data_helper_1xuld5d\n",
      "Hi, I'm a DataHelper. For now, I help with the reddit dataset.\n",
      "At any prompt, press ENTER if you want the default value.\n",
      "Username (default='brandon'): \n",
      "Hello, brandon, I've set your data root to /home/brandon/Datasets/reddit\n",
      "Years to process (default='2007,2008,2009'): \n",
      "These are the files I found:\n",
      "['/home/brandon/Datasets/reddit/raw_data/2007/RC_2007-11',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2007/RC_2007-12',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2007/RC_2007-10',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-12',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-07',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-08',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-03',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-06',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-05',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-09',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-01',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-11',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-10',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-02',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2008/RC_2008-04',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-01',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-03',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-10',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-05',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-02',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-12',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-06',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-08',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-11',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-07',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-04',\n",
      " '/home/brandon/Datasets/reddit/raw_data/2009/RC_2009-09']\n",
      "\n",
      "Maximum memory to use (in GiB) (default='2.00'): 10.\n"
     ]
    }
   ],
   "source": [
    "data_helper = DataHelper()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Playing with the Raw Data\n",
    "Use data helper to load the uncompressed data into a pandas DataFrame."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading year: 2008\n",
      "Returning data from file:\n",
      " /home/brandon/Datasets/reddit/raw_data/2008/RC_2008-11\n",
      "Loading year: 2009\n",
      "Returning data from file:\n",
      " /home/brandon/Datasets/reddit/raw_data/2009/RC_2009-08\n",
      "Loading year: 2010\n",
      "Returning data from file:\n",
      " /home/brandon/Datasets/reddit/raw_data/2010/RC_2010-03\n",
      "Done!\n"
     ]
    }
   ],
   "source": [
    "data = {}\n",
    "years = list(range(2008, 2010 + 1))\n",
    "for year in range(2008, 2010 + 1):\n",
    "    print('Loading year:', year)\n",
    "    data[str(year)] = data_helper.load_random(year=year)\n",
    "print('Done!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remove entries with the comment as \"deleted\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "years = list(range(2008, 2010 + 1))\n",
    "for year in years:\n",
    "    df = data[str(year)]\n",
    "    data[str(year)] = df.loc[df.body != '[deleted]'].reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(-1.0, 15.0), (-1.0, 15.0), (0.0, 13.0)]\n"
     ]
    }
   ],
   "source": [
    "jtplot.style('onedork', ticks=True, fscale=1.5)\n",
    "jtplot.figsize(x=11., y=8.)\n",
    "\n",
    "# Plot the inner 90 of data for 'score'. \n",
    "years = ['2008', '2009', '2010']\n",
    "score_ranges = [tuple(data[y].score.quantile([0.05, .95])) for y in years]\n",
    "print(score_ranges)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from jupyterthemes import jtplot\n",
    "jtplot.style('monokai')\n",
    "# set \"context\" (paper, notebook, talk, or poster)\n",
    "# & font scale (scalar applied to labels, legend, etc.)\n",
    "jtplot.style(ticks=True, grid=False)\n",
    "jtplot.figsize(x=10, y=8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading year: 2008\n",
      "Loading year: 2009\n",
      "Loading year: 2010\n"
     ]
    }
   ],
   "source": [
    "# [Optional] cut down size of data.\n",
    "percent_keep = 0.9\n",
    "for year in range(2008, 2010 + 1):\n",
    "    print('Loading year:', year)\n",
    "    num_keep = int(percent_keep * len(data[str(year)].index))\n",
    "    data[str(year)] = data[str(year)].loc[:num_keep]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['archived', 'author', 'author_flair_css_class', 'author_flair_text',\n",
       "       'body', 'controversiality', 'created_utc', 'distinguished', 'downs',\n",
       "       'edited', 'gilded', 'id', 'link_id', 'name', 'parent_id',\n",
       "       'removal_reason', 'retrieved_on', 'score', 'score_hidden', 'subreddit',\n",
       "       'subreddit_id', 'ups'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_small.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualization: Comment Scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(-1.0, 15.0), (-1.0, 15.0), (0.0, 13.0)]\n",
      "sr: [-1.0, 15.0]\n",
      "nb: 17\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py:1742: UserWarning: This figure includes Axes that are not compatible with tight_layout, so its results might be incorrect.\n",
      "  warnings.warn(\"This figure includes Axes that are not \"\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAwIAAAIqCAYAAACXNP1XAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xd0VPe99/vPzEgz6p1eBaKYjpCEQEhUiWobTBw7dlyS\n2Kkn5Zw8Zz2nPOu5Wc+9J7n3tDjnnFSfxE7cbZwYg+lFIBBF9CZAQgUhIYQqqjPSzNw/JMYMKiCN\nxBjm/VorAX67ffdX47Xmo71/exvmpq12CgAAAIBPMXq7AAAAAAAPHkEAAAAA8EEEAQAAAMAHEQQA\nAAAAH0QQAAAAAHwQQQAAAADwQaaRYyb+xNtFAPBtZrNFc5JSlLHqSS1JX62UtGWaOHmqZDCovLzM\n2+V5XURklFpamu+5nsUSoNRF6Vq+ep2WpK9RcspCxU2cIpPRpBvlpQ+gUu/w9/fXd374d7peWqJb\nt2qVuihdX335O/LzN6uoIK/Lbf7hJ/+i8IgoXb54/gFX23ff/dHfa+LkaTp76pgk6fmXv63URenK\nOXzggdVw9zFT0pYqKTlVuedPP7AaAPQfrggA8Kqo6EH62jd/oMXLVqriRrn27d6m/Xu3q62tTase\n/5KeWPest0v0qpS0pXr2hVfvuZ7ZYtGL3/ie4hPn6UreRe3a9qkO7NulVptVKx9fr3VPf/UBVOsd\nqYsyVHHjuq6VFLmNJyWnatDgId4p6gE4uH+3dm371Ks1HD2cpVGjYzV+wmSv1gGgb/y8XQAA32Xy\n89PTX3lZgUHB+sPv/kM3b1x3LTt6aL+Wr1qnOUnzVVZ6VceOHPRipd4zdtwEGY33/p1NQlKKBg0e\nqt//9jXduP75b//v7OO4uEkqyL80kOU+cBGRUUpMTtXbb/y60zKTyaQVa9brrT/8yguVDbzurnY8\nSK02m3KOHFD6iid0Jf+S5OQdpcDDhCsCALxmTuJ8RccM1q7tm9xCwG27d2xSc3OT4hPmeaG6h8uI\nUWPU1NToFgJuO3o4S5I0ctSYB13WgEtIStGtulqVXivutOzyxfMaNTpWM2cneqEy33H6ZI4iIqM1\nYeJj3i4FQC9xRQCA10yZNlNWa4sunD3Z5fK2tja9+fp/qq6uxm181OhYLViUrhEjR0uSykpLlJW5\nQyXFha51vvujv1f+5VzdKC9TcsoihYVF6GZFubZv+Ytu1dUqY+WTGhc3STarVWdOH9O+Pdtdv838\nh5/8i/bs/EwGg0HxifMUFBSssmtXtWXTBhkMBmWsXKuRo2PV1Nigo4f3d7paMX1WghLnLlDMoMGy\nWa3Kz7uovbu2qLGhXpIUHhGp7/3oH/Tpn99TdMwgTZ+VoKCgYN0ov67MXVtUXHTFdQ4REVGumrIy\ndygrc2eXvbJZrQoKCtbkKdN18cJZt2U11ZX6f//vv5PDbncbHz5ilBYsStfIUWPlcDhUdu2q9u7a\nopsV5b3udeGVPBkMBk2dPlvNzY36/W9+ruamJo0YOUZpizM0vGP70mtXtW/PNl0vLXFtHxAQqGUr\nntCY2PEKDg5V/a065Z4/rax9O2Vva+vyfCXJz89PM2Yn6vTJnC6X79u7XcNGjNTi9NW6fOm8mpua\nut2XJA0aPFRpS5ZrzNjxMpn8VHGjTIcO7HWbR/D8y99WW1ubystKlJicqtbWVr37x98qY9Va2WxW\nnTp+VGmLMxQdM0g11VXavWOzrl0t0tKMNZo8dYYcDocu5Z7Vrm2fqu2Oc5udkKyZsxMVHTNYJpNJ\ndbU1On0yR4cPZnZb7/Mvf1vhEZH61Ws/c32munPnZydm0GAtXLJSY2LHy2Qyqfx6mQ7s26nCK5fd\nthk7boLSFmdo8JDhamyoV3bW7i733VB/S6XXijUnKUV5ly702GMAXyxMFgbgNctXP6Wy0hKd6eaL\nnCS1NDfJecftBhMmTdEzX31FTqdTOYezdLW4QGNi45Q4d4EqbpSpuuqmJCkxOVUxg4ZobGycTuQc\nUklxgSY9Nk0TJ03VlGkz1djYoJPHDysoKFgzZyeqtqZKFR1XJVIXZSh60GANGjREOUcO6OaNck2Z\nPltjYuMUnzhPZaUlOnvquKJjBmtW/FwVF15xhZUFC9OVsfJJlVwt1Mljh1VdXanpM+do2ox4nTtz\nQm2trQoICFRScqqGDhupyKgYHTuarZLiQsVNfEwzZifo5LHDamtrVV1tjQYPGSZJ2rL5YxUXFaip\nsaHLPlmtLZo2Y7amTJulcXGTFRwcIrvDrob6W5Lk1kOp/Qv+8y9/W37+/jp25KCKCvM0YdIUzZ6T\nrNzzp2VtaelVr0eMHC2DwahDWXtUXVWpgvxLGjtugp578VW1tDTr2JEDulZSrDFjxytpXqquFhXo\nVl2tJOnpr3xNo8eO04mcQ8o9f1oOh0OJyQsUHByi/Mu53X42Ro8dr9lzkrV/zzbV1la7xseMHa8x\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f841fe15dd8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "jtplot.style('onedork', ticks=True, fscale=1.5)\n",
    "jtplot.figsize(x=11., y=8.)\n",
    "\n",
    "# Plot the inner 90 of data for 'score'. \n",
    "years = ['2008', '2009', '2010']\n",
    "score_ranges = [tuple(data[y].score.quantile([0.05, .95])) for y in years]\n",
    "print(score_ranges)\n",
    "\n",
    "# Pick the widest range to fit all data in plot.\n",
    "from operator import itemgetter\n",
    "score_range = [min(score_ranges, key=itemgetter(0))[0],\n",
    "               max(score_ranges, key=itemgetter(1))[1]]\n",
    "print('sr:', score_range)\n",
    "num_bins = int(score_range[1] - score_range[0] + 1)\n",
    "print('nb:', num_bins)\n",
    "\n",
    "score_data = [data[y].score for y in years]\n",
    "plt.hist(score_data,\n",
    "         bins=num_bins,\n",
    "         normed=True,\n",
    "         align='left',\n",
    "         label=years,\n",
    "         range=score_range)\n",
    "\n",
    "plt.title('Comment Scores (Normalized)')\n",
    "plt.xlabel('Score')\n",
    "plt.ylabel('Counts')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Visualization: Word Distributions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from nltk import word_tokenize\n",
    "from collections import Counter\n",
    "from itertools import chain\n",
    "\n",
    "jtplot.style('onedork', ticks=True, fscale=1.5)\n",
    "jtplot.figsize(x=11., y=8.)\n",
    "\n",
    "#$word_tokenize(data['2008'].loc[0, 'body'])\n",
    "pd.set_option('display.max_colwidth', 1000)\n",
    "#pd.DataFrame(data['2008']['body']).head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from nltk import FreqDist\n",
    "\n",
    "wt = Counter(chain.from_iterable(data['2008']['body']))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time to run parallel_map_list: 13.947 seconds.\n",
      "DONE\n"
     ]
    }
   ],
   "source": [
    "tokenized = parallel_map_list(fn=DataHelper.word_tokenizer, \n",
    "                              iterable=data['2008'].body.values)\n",
    "print('DONE')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "data_helper.set_word_freq(Counter(chain.from_iterable(tokenized)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "most_comm = data_helper.word_freq.most_common(20)\n",
    "words, counts = zip(*most_comm)\n",
    "\n",
    "x_labels = words\n",
    "counts_series = pd.Series.from_array(counts)\n",
    "\n",
    "plt.figure(figsize=(16, 10))\n",
    "ax = counts_series.plot(kind='bar')\n",
    "ax.set_title('Most Common Words 2008')\n",
    "ax.set_ylabel('Counts')\n",
    "ax.set_xlabel('Words')\n",
    "ax.set_xticklabels(x_labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Preprocessing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "PROJECT_ROOT = '/home/brandon/Documents/DeepChatModels'\n",
    "REDDIT_DIR = '/home/brandon/Datasets/reddit'\n",
    "SOURCE_DIR = os.path.join(REDDIT_DIR, 'raw_data')\n",
    "TARGET_DIR = os.path.join(REDDIT_DIR, 'raw_data_columns_removed')\n",
    "YEAR = '2009'\n",
    "TARGET_FILE = os.path.join(TARGET_DIR, YEAR + '_cols_removed.json')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "data_helper = DataHelper()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "data_helper.file_counter = 9\n",
    "print(data_helper.file_paths[data_helper.file_counter:])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load 2007 Data in DF"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "df = data_helper.safe_load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print(\"df has {} rows.\".format(len(df.index)))\n",
    "print(\"df has columns:\\n\", df.columns)\n",
    "df.body.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "df = remove_extra_columns(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print(\"df has {} rows.\".format(len(df.index)))\n",
    "print(\"df has columns:\\n\", df.columns)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "DataHelper.df_to_json(df, orient='records', lines=False, target_file=TARGET_FILE)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## In One Function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def remove_extra_columns_and_save()\n",
    "    print(\"Removing extra columns . . . \")\n",
    "    df = remove_extra_columns(df)\n",
    "    print(\"Saving to {} . . . \".format(TARGET_FILE))\n",
    "    DataHelper.df_to_json(\n",
    "        df, \n",
    "        orient='records', \n",
    "        lines=False, \n",
    "        target_file=TARGET_FILE)\n",
    "    print(\"Done!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Loading back later"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "df_loaded = pd.read_json(target_file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "len(df_loaded)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "file_names = []\n",
    "for y in ['2007', '2008', '2009']:\n",
    "    file_names.append(y + '_cols_removed.json')\n",
    "file_names = file_names[:-1]\n",
    "#file_names[-1] = '2009_cols_removed_part_1.json'\n",
    "#file_names.append('2009_cols_removed_part_2.json')\n",
    "file_names = [os.path.join(TARGET_DIR, fname) for fname in file_names]\n",
    "pprint(file_names)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "list_ = []\n",
    "for file_path in file_names:\n",
    "    print('file:', file_path)\n",
    "    sys.stdout.flush()\n",
    "    list_.append(pd.read_json(file_path))\n",
    "df = pd.concat(list_).reset_index()\n",
    "del list_\n",
    "list_ = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "TARGET_FILE = os.path.join(TARGET_DIR, '2007-8_cols_removed.json')\n",
    "DataHelper.df_to_json(df, orient='records', lines=False, target_file=TARGET_FILE)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Stage 2: Regex, Long Comments, and Contractions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Regex"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataFrame loaded.\n"
     ]
    }
   ],
   "source": [
    "TARGET_FILE = os.path.join(TARGET_DIR, YEAR+'_cols_removed_part_1.json')\n",
    "df = pd.read_json(TARGET_FILE)\n",
    "print('DataFrame loaded.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time to run regex_replacements: 583.041 seconds.\n",
      "Regex replacements done.\n"
     ]
    }
   ],
   "source": [
    "from data.reddit_preprocessor import regex_replacements\n",
    "df = regex_replacements(df)\n",
    "print('Regex replacements done.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "TARGET_FILE = os.path.join(TARGET_DIR, '2007-8_regex_replaced.json')\n",
    "DataHelper.df_to_json(df, orient='records', lines=False, target_file=TARGET_FILE)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Long Comments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "TARGET_FILE = os.path.join(TARGET_DIR, '2007-8_regex_replaced.json')\n",
    "df = pd.read_json(TARGET_FILE)\n",
    "print('DataFrame loaded from', TARGET_FILE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "reload(data)\n",
    "from data.reddit_preprocessor import remove_large_comments, expand_contractions\n",
    "df = remove_large_comments(df=df, max_len=20)\n",
    "df = expand_contractions(df)\n",
    "print('Remove large comments and contractions done.')\n",
    "\n",
    "TARGET_FILE = os.path.join(TARGET_DIR, YEAR+'_large_comments_contractions.json')\n",
    "DataHelper.df_to_json(df, orient='records', lines=False, target_file=TARGET_FILE)\n",
    "\n",
    "print('done')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Stage 3: Parallel Calls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataFrame loaded from /home/brandon/Datasets/reddit/raw_data_columns_removed/2007-8_large_comments_contractions.json\n"
     ]
    }
   ],
   "source": [
    "from data.reddit_preprocessor import parallel_map_list\n",
    "from data.reddit_preprocessor import data_helper\n",
    "TARGET_FILE = os.path.join(TARGET_DIR, '2007-8_large_comments_contractions.json')\n",
    "df = pd.read_json(TARGET_FILE)\n",
    "print('DataFrame loaded from', TARGET_FILE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time to run parallel_map_list: 19.272 seconds.\n"
     ]
    }
   ],
   "source": [
    "from collections import Counter\n",
    "from itertools import chain\n",
    "sentences = parallel_map_list(fn=DataHelper.word_tokenizer, iterable=df.body.values)\n",
    "data_helper.set_word_freq(Counter(chain.from_iterable(sentences)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time to run parallel_map_list: 215.748 seconds.\n"
     ]
    }
   ],
   "source": [
    "from data.reddit_preprocessor import sentence_score\n",
    "df['score'] = parallel_map_list(fn=sentence_score, iterable=sentences)\n",
    "del sentences"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAboAAAEgCAYAAADCCragAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X9Q1PeB//HnKpYieoeC7CJtCSomp9OMJLme4TswHVYN\nXt0FzMUgdZLUZKbkF171cuYwBloL1kmZqk2mcv6ReLX8sHOEH3a8UZfTc8aSDIZcWs0kOKkmo+xu\nXI9DCEFXPt8/GPYkifxYMcKb12PGGXi/9/N5vz/v2dmX78/nzXttlmVZiIiIGGrKne6AiIjI7aSg\nExERoynoRETEaAo6ERExmoJORESMpqATERGjKehERMRoCjoRETGagk5ERIymoBMREaMp6ERExGgR\nd7oDX7fuz3o4d/4Cf/1XM4iImHSXLyIyYQWDQf63s4u7khKJnh414uMm3Sf9ufMXOHT4xJ3uhoiI\nhGnlinQW/82CEb9+0gXdX//VDKB/oGJnx9zh3oiIyEgFLndw6PCJ0Of4SE26oBu4XRk7OwaHPe4O\n90ZEREZrtI+dtBhFRESMpqATERGjKehERMRoCjoRETGagk5ERIymoBMREaMp6ERExGgKOhERMZqC\nTkREjDbpdkYZC9/b9MdBv79d/uAd6omIiAxHMzoRETGagk5ERIw2oluXTz75JFeuXAHgO9/5DiUl\nJXR2dpKdnc28efMA+OY3v8m+ffuA/u8M2rZtG62trURERFBUVMQDDzwAgN/v58UXXyQQCBAbG8sv\nfvEL4uPjAWhpaaGsrIxgMEhqaipbt24Nbd5ZWVlJdXU1AHl5eeTn54/hMIiIiKlGNKPbuXMnBw4c\n4MCBAzgcjlCgzZkzh5qaGmpqakJlAA0NDfT09NDQ0MCOHTsoKSmhr68PgF27dpGVlUV9fT1ZWVns\n3r0bgL6+PkpKStixY0fo+MbGRgDOnz9PdXU1VVVVVFVVUV1dzccffzymAyEiImYaUdDNnDkT6A+j\nzz//HJvNNuTrPR4Pubm5AKSkpDB79mzOnDkDwPHjx3G5XAC4XC6OHTsGwOnTp4mNjSUlJQWAnJwc\nPB4PAE1NTSxfvpzo6Giio6NZtmwZTU1No7xUERGZjEb8jO65557D6XRy7tw5nnjiCQAuX75Mfn4+\n69at4w9/+EPotX6/H7vdHvo9ISEBr9dLR0cHkZGRREX1fwV6VFQUkZGRdHR04PP5cDgcoWMcDgc+\nnw8An8836HwOhwOv1xveFYuIyKQy4j8vePXVV7l+/Tq//vWvOXDgAPn5+Rw6dIhZs2Zx8eJFCgoK\nSExMZMmSJViW9ZXnuFn5cHXh2rNnDxUVFYPKZsfOYaVr7Zi3JSIi49OoVl1OnToVl8vFwYMH+cY3\nvsGsWbMAmDt3Lt///vd57733ALDb7aHZGEB7ezt2u52YmBh6e3vp6ekBoKenh97eXmJiYr40S/N6\nvaFFKl88n9frHTTDu5mCggJaW1sH/fvd7ypHc8kiIjLBDRt0nZ2dBAKB0O9Hjx5l/vz5XL58mWAw\nGHpNc3MzCxcuBMDpdFJXVwdAW1sbgUCAxYsXY7PZyMjICC0yaWxsJCMjA4BFixZx6dIl2traAKiv\nr8fpdAKQmZnJkSNH6O7upru7m6NHj5KZmTlWYyAiIgYb9tZlZ2cnmzdv5tq1a1iWRXJyMps3b6a1\ntZXf/OY3TJkyhb6+PtxuN0uXLgX6F5m0trbicrmYNm0aJSUlTJnSn6mFhYUUFRWxf/9+4uLi2L59\nO9A/WywuLg61tWTJktCilaSkJNasWUNeXh7Q/+cFSUlJt2VARETELDbrdjwcG8e8vkvsr25kXZ4L\nhz0urHNoCzARka9fuJ/f2hlFRESMpqATERGjKehERMRoCjoRETGagk5ERIymoBMREaMp6ERExGgK\nOhERMZqCTkREjKagExERoynoRETEaAo6ERExmoJORESMpqATERGjKehERMRoCjoRETGagk5ERIym\noBMREaMp6ERExGgRd7oDJvjepj+Gfn67/ME72BMREfkizehERMRoCjoRETGagk5ERIw2omd0Tz75\nJFeuXAHgO9/5DiUlJcyYMYPDhw/z2muvYVkWy5Yto7CwMHTMrl278Hg82Gw2nn32WVasWAFAV1cX\nW7Zs4S9/+QszZszgZz/7GQsWLADg7NmzbN26le7ubpKTkykrKyM6OhpgyLZERERuZkQzup07d3Lg\nwAEOHDiAw+Fg3759XLlyhfLycvbu3UttbS2nTp3irbfeAqC5uZnW1lZqa2vZu3cv5eXldHV1AbBv\n3z6Sk5NpaGjg6aefpqysLNROaWkpzzzzDA0NDSQnJ/PGG28ADNmWiIjIUEYUdDNnzgSgr6+Pzz//\nHJvNxsmTJ7nvvvuIj48nIiICl8uFx+MBwOPx4HK5iIiIID4+ntTUVE6ePBmqy83NBSA9PZ1PPvmE\nQCBAIBDgwoULpKenA5CTkxM631BtiYiIDGXEz+iee+45nE4n586d44knnsDn8+FwOEL1DocDn88H\ngN/vx263h+oSEhLwer0A+Hy+QXUDx92sfOCYm7UlIiIylBH/Hd2rr77K9evX+fWvf82BAweYMuXm\nGWlZ1qjrhjomXHv27KGiomJQ2ezYOax0rR3ztkREZHwa1arLqVOn4nK5OHjwIHa7PTRLA/B6vcTH\nxwNgt9sHzbja29tDs7Uvzsa8Xi92u/1LxwyUD5zvZm0NpaCggNbW1kH/fve7ytFcsoiITHDDBl1n\nZyeBQCD0+9GjR5k/fz5paWmcOnUKv99PMBjk4MGDOJ1OAJxOJ42NjQSDQfx+P++88w5paWkAZGZm\n8uabbwJw4sQJEhMTiY2NJS4ujrlz53LixAkA6urqyMzMBBiyLRERkaEMe+uys7OTzZs3c+3aNSzL\nIjk5mc2bNzNz5kw2btzIU089hWVZOJ1Oli5dCsDSpUtpbm4mNzcXm83Gxo0bQwtaHn/8cbZs2YLb\n7Wb69Ols27Yt1FZRUREvv/wyr7zyCnfddRelpaUAQ7YlIiIyFJt1Ox6OjWNe3yX2VzeyLs+Fwx4X\n1jlu3Nvyi7TXpYjI7RHu57d2RhEREaMp6ERExGgKOhERMZqCTkREjKagExERoynoRETEaAo6EREx\nmoJORESMpqATERGjKehERMRoCjoRETGagk5ERIw24i9elZG5ccNnbfAsInLnaUYnIiJGU9CJiIjR\nFHQiImI0BZ2IiBhNQSciIkZT0ImIiNEUdCIiYjQFnYiIGE1BJyIiRlPQiYiI0YbdAszr9VJcXMyn\nn36KzWYjPT2dDRs2cOrUKQoLC/n2t78NwLe//W1++ctfAtDV1cWWLVv4y1/+wowZM/jZz37GggUL\nADh79ixbt26lu7ub5ORkysrKiI6OBuDw4cO89tprWJbFsmXLKCwsDPVj165deDwebDYbzz77LCtW\nrBjzwRAREfMMO6ObOnUqhYWF1NbWUl1dzZ/+9Cc8Hg8AixYtoqamhpqamlDIAezbt4/k5GQaGhp4\n+umnKSsrC9WVlpbyzDPP0NDQQHJyMm+88QYAV65coby8nL1791JbW8upU6d46623AGhubqa1tZXa\n2lr27t1LeXk5XV1dYzkOIiJiqGGDbs6cOSxevBiAadOmkZKSgs/nG/IYj8dDbm4uAOnp6XzyyScE\nAgECgQAXLlwgPT0dgJycnFBonjx5kvvuu4/4+HgiIiJwuVyhOo/Hg8vlIiIigvj4eFJTUzl58mT4\nVy0iIpPGqJ7RdXR0cOzYMR58sH9X/g8++IC8vDzWr18/KHh8Ph92uz30u8PhwOfz3bR84BiHw/GV\ndX6/f9BxCQkJeL3e0XRdREQmqRF/Tc/Vq1d54YUXyM/PZ968ecTHx3Po0CFmzJjBhx9+yHPPPcfr\nr79OYmIilmV95TluVj6ccI/bs2cPFRUVg8pmx85hpWttWOcTEZGJZ0RBd/36dYqKirj77rt57LHH\nAJgxY0aofuHChdx77728//77JCYmhmZjSUlJQP+CFrvdjmVZg257DpQD2O123n///UF18fHxobob\nj2tvb+eee+4Ztt8FBQUUFBQMKvP6LrG/unEkly0iIgYY0a3Ln//850RHR7Np06ZQ2aeffhqaafl8\nPv785z8zf/58ADIzM3nzzTcBOHHiBImJicTGxhIXF8fcuXM5ceIEAHV1dWRmZgKQlpbGqVOn8Pv9\nBINBDh48iNPpBMDpdNLY2EgwGMTv9/POO++QlpY2RkMgIiImG3ZG9+6771JXV8eCBQvIy8sDIDs7\nmylTpvD73/+eiIgILMvi+eefJzk5GYDHH3+cLVu24Ha7mT59Otu2bQudr6ioiJdffplXXnmFu+66\ni9LSUgBmzpzJxo0beeqpp7AsC6fTydKlSwFYunQpzc3N5ObmYrPZ2LhxIzNnzhzzwRAREfPYrHAf\ngE1QA7cu1+W5cNjjwjrH9zb9cUSve7v8wbDOLyIiXxbu57d2RhEREaMp6ERExGgKOhERMZqCTkRE\njKagExERoynoRETEaAo6ERExmoJORESMpqATERGjKehERMRoCjoRETGagk5ERIymoBMREaMp6ERE\nxGgKOhERMZqCTkREjKagExERoynoRETEaAo6ERExmoJORESMpqATERGjKehERMRoEXe6Ayb73qY/\nDvr97fIH71BPREQmL83oRETEaMMGndfr5cc//jGrV6/m4YcfZufOnViWBUBlZSVutxu3201lZWXo\nmGAwSHFxMW63m9WrV9PS0hKq8/v9rF+/nuzsbNavX4/f7w/VtbS0sHr1atxuN8XFxQSDwVDdzdoS\nEREZyrBBN3XqVAoLC6mtraW6upo//elPeDwezp8/T3V1NVVVVVRVVVFdXc3HH38MQENDAz09PTQ0\nNLBjxw5KSkro6+sDYNeuXWRlZVFfX09WVha7d+8GoK+vj5KSEnbs2BE6vrGxEWDItkRERIYybNDN\nmTOHxYsXAzBt2jRSUlLw+Xw0NTWxfPlyoqOjiY6OZtmyZTQ1NQHg8XjIzc0FICUlhdmzZ3PmzBkA\njh8/jsvlAsDlcnHs2DEATp8+TWxsLCkpKQDk5OTg8XgAhmxLRERkKKN6RtfR0cGxY8d48MEH8fl8\n2O32UJ3D4cDr9QL9tydvrEtISMDr9dLR0UFkZCRRUVEAREVFERkZSUdHBz6fD4fDMeh8Pp8PYMi2\nREREhjLiVZdXr17lhRdeID8/n3nz5g352oFneCMtH64uXHv27KGiomJQ2ezYOax0rR3ztkREZHwa\nUdBdv36doqIi7r77bh577DEA7HZ7aMYF/YtWBmZdA3UDgdje3o7dbicmJobe3l56enqIioqip6eH\n3t5eYmJivjRL83q9xMfHD9vWUAoKCigoKBhU5vVdYn9140guW0REDDCiW5c///nPiY6OZtOmTaGy\nzMxMjhw5Qnd3N93d3Rw9epTMzEwAnE4ndXV1ALS1tREIBFi8eDE2m42MjIzQIpPGxkYyMjIAWLRo\nEZcuXaKtrQ2A+vp6nE7nsG2JiIgMZdgZ3bvvvktdXR0LFiwgLy8PgOzsbPLz81mzZk2oLC8vj6Sk\nJKB/kUlraysul4tp06ZRUlLClCn9mVpYWEhRURH79+8nLi6O7du3A/2rO4uLi9m8eTPXrl1jyZIl\noUUrSUlJN21LRERkKDbrdjwcG8cGbl2uy3PhsMeFdY4v7ngyUtoZRUQkfOF+fmtnFBERMZqCTkRE\njKagExERoynoRETEaAo6ERExmoJORESMpqATERGjKehERMRoCjoRETGagk5ERIymoBMREaMp6ERE\nxGgKOhERMZqCTkREjKagExERoynoRETEaAo6ERExmoJORESMpqATERGjKehERMRoEXe6A5PJ9zb9\nMfTz2+UP3sGeiIhMHprRiYiI0RR0IiJitBEFXWlpKStWrCA1NTVU1tLSQlpaGo8++iiPPvoo//RP\n/xSq6+rqYsOGDbjdbvLz8zl79myo7uzZs6xduxa3282GDRvo7u4O1R0+fJjs7Gzcbje7d+8e1Idd\nu3bhdrvJzs7m8OHDYV+wiIhMLiMKuqysLKqqqr5UvmjRImpqaqipqeGXv/xlqHzfvn0kJyfT0NDA\n008/TVlZWaiutLSUZ555hoaGBpKTk3njjTcAuHLlCuXl5ezdu5fa2lpOnTrFW2+9BUBzczOtra3U\n1tayd+9eysvL6erqupXrFhGRSWJEQXf//fcTGxs74pN6PB5yc3MBSE9P55NPPiEQCBAIBLhw4QLp\n6ekA5OTk4PF4ADh58iT33Xcf8fHxRERE4HK5QnUejweXy0VERATx8fGkpqZy8uTJUV2oiIhMTrf0\njO6DDz4gLy+P9evXDwoen8+H3W4P/e5wOPD5fDctHzjG4XB8ZZ3f7x90XEJCAl6v91a6LiIik0TY\nf15wzz33cOjQIWbMmMGHH37Ic889x+uvv05iYiKWZX3lMTcrH064x+3Zs4eKiopBZbNj57DStTas\n84mIyMQTdtDNmDEj9PPChQu59957ef/990lMTAzNxpKSkgDwer3Y7XYsywrN0m4sB7Db7bz//vuD\n6uLj40N1Nx7X3t7OPffcM2wfCwoKKCgoGFTm9V1if3VjGFcsIiITUdi3Lj/99NPQTMvn8/HnP/+Z\n+fPnA5CZmcmbb74JwIkTJ0hMTCQ2Npa4uDjmzp3LiRMnAKirqyMzMxOAtLQ0Tp06hd/vJxgMcvDg\nQZxOJwBOp5PGxkaCwSB+v5933nmHtLS08K9aREQmjRHN6H7605+GnsE99NBDpKWlcffdd/P73/+e\niIgILMvi+eefJzk5GYDHH3+cLVu24Ha7mT59Otu2bQudq6ioiJdffplXXnmFu+66i9LSUgBmzpzJ\nxo0beeqpp7AsC6fTydKlSwFYunQpzc3N5ObmYrPZ2LhxIzNnzhzTgRARETPZrHAfgE1QA7cu1+W5\ncNjjwjrHjVt5hUtbgImIjE64n9/aGUVERIymoBMREaMp6ERExGgKOhERMZqCTkREjKagExERoyno\nRETEaAo6ERExmoJORESMFvamznJrvri7inZKERG5PTSjExERoynoRETEaAo6ERExmoJORESMpqAT\nERGjKehERMRoCjoRETGagk5ERIymoBMREaMp6ERExGgKOhERMZqCTkREjKZNnceJGzd51gbPIiJj\nZ9gZXWlpKStWrCA1NXVQeWVlJW63G7fbTWVlZag8GAxSXFyM2+1m9erVtLS0hOr8fj/r168nOzub\n9evX4/f7Q3UtLS2sXr0at9tNcXExwWBw2LZERESGM2zQZWVlUVVVNajs/PnzVFdXU1VVRVVVFdXV\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f734b3c2630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from jupyterthemes import jtplot\n",
    "jtplot.style('onedork')\n",
    "jtplot.style(ticks=True, grid=False)\n",
    "jtplot.figsize(aspect=1.2)\n",
    "plt.hist(df['score'].values, bins=100,\n",
    "        range=(0., df['score'].quantile(0.7)))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Final Stage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Prepping for the grand finale.\n",
      "Time to run children_dict: 4.701 seconds.\n",
      "Final processed file has 306164 samples total.\n"
     ]
    }
   ],
   "source": [
    "# Keep the desired percentage of lowest-scored sentences. (low == good)\n",
    "from data.reddit_preprocessor import children_dict\n",
    "keep_best_percent = 0.7\n",
    "df = df.loc[df['score'] < df['score'].quantile(keep_best_percent)]\n",
    "\n",
    "print('Prepping for the grand finale.')\n",
    "comments_dict = pd.Series(df.body.values, index=df.name).to_dict()\n",
    "root_to_children = children_dict(df)\n",
    "data_helper.generate_files(\n",
    "            from_file_path=\"from_file.txt\",\n",
    "            to_file_path=\"to_file.txt\",\n",
    "            root_to_children=root_to_children,\n",
    "            comments_dict=comments_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exploration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "df.style.set_properties(subset=['text'], **{'width': '800px'})\n",
    "def get_comments(df, n=10):\n",
    "    i = 0\n",
    "    while i < len(df.index):\n",
    "        yield df.loc[i:i+n]['body']\n",
    "        i += n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "gen = get_comments(df, 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "comments = next(gen)\n",
    "for comment in comments:\n",
    "    print(comment)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
